import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import RadioGroup from './radioGroup';
import { shallowEqual } from './utils';
import './style.less';

export default class Radio extends React.Component {
    static Group = RadioGroup;

    static propTypes = {
        value: PropTypes.oneOfType([
            PropTypes.string,
            PropTypes.number,
        ]),

        defaultValue: PropTypes.oneOfType([
            PropTypes.string,
            PropTypes.number,
        ]),
        children: PropTypes.node,
        onChange: PropTypes.func,
        className: PropTypes.string,
        disabled: PropTypes.bool,
        checked: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),

    };

    static defaultProps = {
        onChange: null,
        value: null,
        defaultValue: null,
        children: null,
        className: null,
        disabled: false,
        checked: false,
    };

    static contextTypes = {
        radioGroup: PropTypes.any,
    };

    state = {
        checked: false,
    };


    shouldComponentUpdate(nextProps, nextState, nextContext) {
        return (
            !shallowEqual(this.props, nextProps)
            || !shallowEqual(this.state, nextState)
            || !shallowEqual(this.context.radioGroup, nextContext.radioGroup)
        );
    }

    onChange = (e) => {
        const { disabled } = this.props;

        if (disabled) {
            return;
        }

        if (!this.context.radioGroup) {
            this.setState({
                checked: e.target.checked,
            });
        }

        if (this.props.onChange) {
            this.props.onChange(e);
        }

        if (this.context.radioGroup && this.context.radioGroup.onChange) {
            this.context.radioGroup.onChange(e);
        }
    };

    renderRadio = () => {
        const { props, context } = this;
        const {
            className, children, value, ...restProps
        } = props;
        const { radioGroup } = context;
        const prefixCls = 'wpt-radio';
        const radioProps = { ...restProps };

        radioProps.onChange = this.onChange;

        if (radioGroup) {
            radioProps.name = radioGroup.name;
            radioProps.checked = props.value == radioGroup.value;
            radioProps.disabled = props.disabled || radioGroup.disabled;
        } else {
            radioProps.checked = this.state.checked;
            radioProps.disabled = props.disabled;
        }
        const wrapperClassString = cx(className, {
            [`${prefixCls}-wrapper`]: true,
            [`${prefixCls}-wrapper-checked`]: radioProps.checked,
            [`${prefixCls}-wrapper-disabled`]: radioProps.disabled,
        });

        const inputCls = `${prefixCls}-input`;
        const radioCls = cx({
            [`${prefixCls}`]: true,
            [`${prefixCls}-checked`]: radioProps.checked,
        });

        const innerCls = `${prefixCls}-inner`;

        return (
            // eslint-disable-next-line jsx-a11y/label-has-associated-control
            <label
                className={wrapperClassString}
            >
                <span className={radioCls}>
                    <input type="radio" className={inputCls} value={value}
                        checked={radioProps.checked}
                        onChange={radioProps.onChange}
                        disabled={radioProps.disabled}
                        name={radioProps.name}/>

                    <span className={innerCls}/>
                </span>

                {children !== undefined ? <span>{children}</span> : null}
            </label>
        );
    };

    render() {
        return this.renderRadio();
    }
}
